//
//  MMMemoryWarningSimulator.m
//  MindMeister
//
//  Created by Joerg Simon on 10/11/10.
//

#import "MMMemoryWarningSimulator.h"
#import <UIKit/UIApplication.h>

@interface MMMemoryWarningSimulator ()

@property (retain) NSThread *allocThread;

-(void)allocData:(NSUInteger)len;
-(void)stopAllocatingMemory;
-(void)increaseMemoryOnBackground;
@end

#define DEBUG_SIMULATE_MEM_ON_DEVICE 1
#define DEBUG_SIM_MEM_LOOP 0

static MMMemoryWarningSimulator *sharedManager = nil;

@implementation MMMemoryWarningSimulator
@synthesize allocThread;

-(void)createMemoryWarning {
#if (DEBUG_SIMULATE_MEM_ON_DEVICE)
	NSLog(@"");
#endif
	
#if (TARGET_IPHONE_SIMULATOR)
	// on the simulator, we don't want this to happen, since it would loop forever untill we
	// manually simulate a memory warning, and could really slow you computer with garbage memory
	return;
#endif
	
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopAllocatingMemory) name: UIApplicationDidReceiveMemoryWarningNotification object:nil];
	NSThread *t = [[NSThread alloc] initWithTarget:self selector:@selector(increaseMemoryOnBackground)
											object:nil];
	self.allocThread = t;
	[t release];
	[self.allocThread start];
	
	//[self performSelectorInBackground:@selector(increaseMemoryOnBackground) withObject:nil];
}

-(void)increaseMemoryOnBackground {
#if (DEBUG_SIMULATE_MEM_ON_DEVICE)
	NSLog(@"");
#endif
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSUInteger start = 100;
	NSUInteger end = INT_MAX;
	
	for (int len = start; start < end; len++) {
		if (self.allocThread.isCancelled) {
#if (DEBUG_SIMULATE_MEM_ON_DEVICE)
			//MMLOGFULL(@"cancelling thread");
#endif
			[pool release];
			self.allocThread = nil;
			return;
		}
		[self allocData:200];
		
	}
	[pool release];
}

-(void)allocData:(NSUInteger)len {
#if (DEBUG_SIMULATE_MEM_ON_DEVICE & DEBUG_SIM_MEM_LOOP)
	NSLog(@" allocating data with lenght: %d", len);
#endif
	[NSMutableData dataWithLength:len];
}

-(void)stopAllocatingMemory {
#if (DEBUG_SIMULATE_MEM_ON_DEVICE)
	//MMLOGFULL(@"received mem warning");
#endif
	[self.allocThread cancel];
	//[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(increaseMemoryOnBackground) object:nil];
	[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
}


//======================= SINGLETON STD STUFF ==================================

+ (MMMemoryWarningSimulator*)sharedManager
{
    if (sharedManager == nil) {
        sharedManager = [[super allocWithZone:NULL] init];
    }
    return sharedManager;
}

+ (id)allocWithZone:(NSZone *)zone
{
	// is's a singleton, we don't need that:
#pragma unused (zone)
    return [[self sharedManager] retain];
}

- (id)copyWithZone:(NSZone *)zone
{
	// is's a singleton, we don't need that:
#pragma unused (zone)
    return self;
}

- (id)retain
{
    return self;
}

- (NSUInteger)retainCount
{
    return NSUIntegerMax;  //denotes an object that cannot be released
}

- (oneway void)release
{
    //do nothing
}

- (id)autorelease
{
    return self;
}

@end